package main

import (
	"bytes"
	"fmt"
	"net"
	"strings"
)

const (
	TextBlack = iota + 30
	TextRed
	TextGreen
	TextYellow
	TextBlue
	TextMagenta
	TextCyan
	TextWhite
)

//将说明打印成蓝色
func debug(s string) {
	fmt.Printf("\x1b[0;%dm%s\x1b[0m\n", TextBlue, s)
}



func main() {
	debug("1, 测试IP是否在地址池范围内: 192.168.1.1, 地址池：192.168.1.2-192.168.2.0")
	fmt.Println(IsIPinPool("192.168.1.1", "192.168.1.2-192.168.2.0"))

	debug("2, 测试IP是否在地址池范围内: 192.168.1.3, 地址池：192.168.1.2-192.168.2.0")
	fmt.Println(IsIPinPool("192.168.1.3", "192.168.1.2-192.168.2.0"))

	debug("3, 测试IP是否在地址池范围内: 192.168.1.3, 地址池：192.168.1.3-192.168.1.255")
	fmt.Println(IsIPinPool("192.168.1.3", "192.168.1.3-192.168.1.255"))

	debug("4, 测试IP是否在地址池范围内: 192.168.1.3, 地址池：192.168.1.2-192.168.1.3")
	fmt.Println(IsIPinPool("192.168.1.3", "192.168.1.2-192.168.1.3"))

	debug("5, 测试IP是否在网段之内: 192.168.1.3, 地址段 192.168.1.3/24")
	fmt.Println(IsIPinSegment("192.168.1.3", "192.168.1.3/24"))

	debug("6, 测试IP是否在网段之内: 192.168.1.3, 地址段 192.168.2.0/24")
	fmt.Println(IsIPinSegment("192.168.1.3", "192.168.2.0/24"))

	debug("7, 测试IP是否在网段之内: 192.168.1.3, 地址段 192.168.1.3/32")
	fmt.Println(IsIPinSegment("192.168.1.3", "192.168.1.3/32"))

	debug("8, 测试IP是否在网段之内: 192.168.1.1, 地址段 192.168.1.3/32")
	fmt.Println(IsIPinSegment("192.168.1.1", "192.168.1.3/32"))

	debug("9, 打印网段中所有IP")
	showIPinCIDR("10.200.8.240/28")
}

func IsIPinSegment(ip string, segment string) bool {
	_, ipNet, _ := net.ParseCIDR(segment)
	return ipNet.Contains(net.ParseIP(ip))
}

func IsIPinPool(ip string, pool string) bool {
	ipScope := strings.Split(pool, "-")
	startIp := net.ParseIP(ipScope[0])
	endIp := net.ParseIP(ipScope[1])
	curIp := net.ParseIP(ip)

	if bytes.Compare(curIp, startIp) >= 0 && bytes.Compare(curIp, endIp) <= 0 {
		return true
	}

	return false
}


func IP2Uint32(ip net.IP) uint32 {
	return uint32(ip[0])<<24 + uint32(ip[1])<<16 + uint32(ip[2]) << 8 + uint32(ip[3])
}
func Mask2Uint32(ip net.IPMask) uint32 {
	return uint32(ip[0])<<24 + uint32(ip[1])<<16 + uint32(ip[2]) << 8 + uint32(ip[3])
}

func Ulong2IP(u uint32) net.IP {
	return net.IPv4(byte((u>>24) & 0xff), byte((u>>16) & 0xff), byte((u>>8) & 0xff), byte(u & 0xff))
}

func showIPinCIDR(segment string) {
	ip, ipNet, _ := net.ParseCIDR(segment)
	fmt.Println(ip)
	fmt.Println(ipNet.IP, ipNet.Mask)

	mask := net.ParseIP("255.255.255.255")
	start := IP2Uint32(ipNet.IP) & Mask2Uint32(ipNet.Mask)
	count := IP2Uint32(mask) - Mask2Uint32(ipNet.Mask)


	fmt.Println(start, count)
	for i := start; i < start + count; i++ {
		fmt.Printf("%s ", Ulong2IP(i))
		if i & 3 == 0 {
			fmt.Printf("\n")
		}
	}


}
